package plp.expressions2.util;

import plp.AppletInterpretadorPLP;
import plp.expressions2.expression.ExpBinaria;
import plp.expressions2.expression.ExpEquals;
import plp.expressions2.expression.ExpUnaria;
import plp.expressions2.expression.Expressao;
import plp.expressions2.expression.Id;
import plp.expressions2.expression.Valor;
import plp.expressions2.memory.AmbienteCompilacao;
import plp.expressions2.parser.Token;
import plp.functional1.expression.Aplicacao;
import plp.imperative1.command.Atribuicao;
import plp.imperative1.command.IfThenElse;
import plp.imperative1.command.While;

public class Visitor implements LinguagemVisitor {

	public static boolean achouErro = false;
	
	public void visit(Expressao exp){
		AppletInterpretadorPLP.SelecionarErro(exp.getLineExpression(),
				exp.getBeginColumnExpression(),
				exp.getEndColumnExpression());
	}

	/**
	 * visit genérico para as expressões binárias.
	 */
	public void visit(ExpBinaria expBinaria, AmbienteCompilacao ambiente) throws VisitorException {
		if(!achouErro) {
			achouErro = true;
			if (!(expBinaria.getEsq().getTipo(ambiente) == expBinaria.getTipo(ambiente))) {
				AppletInterpretadorPLP.SelecionarErro(expBinaria.getEsq().getLineExpression(),
						expBinaria.getEsq().getBeginColumnExpression(),
						expBinaria.getEsq().getEndColumnExpression());
			} else {
				AppletInterpretadorPLP.SelecionarErro(expBinaria.getDir().getLineExpression(),
						expBinaria.getDir().getBeginColumnExpression(),
						expBinaria.getDir().getEndColumnExpression());
			}
		}
	}
	
	/**
	 * visit genérico para as expressões unárias.
	 */
	public void visit(ExpUnaria expUna, AmbienteCompilacao ambiente) {
		if(!achouErro) {
			achouErro = true;
			AppletInterpretadorPLP.SelecionarErro(expUna.getExp().getLineExpression(),
						expUna.getExp().getBeginColumnExpression(),
						expUna.getExp().getEndColumnExpression());
		}
	}

	public void visit(Token token) {
		AppletInterpretadorPLP.SelecionarErro(token.beginLine);
	}
	

	/* O visit do equals é implementado mesmo tendo um genérico para binária, pois não sabemos qual dos lados 
	 * é o que está errado, então marcamos toda a expresão	 */
	public void visit(ExpEquals expEquals) {
		AppletInterpretadorPLP.SelecionarErro(expEquals.getLineExpression());
	}

	@Override
	public void visit(Valor valor, AmbienteCompilacao ambiente ) throws VisitorException {
		System.out.println("Valor");
	}

	@Override
	public void visit(Id id, AmbienteCompilacao ambiente) throws VisitorException {
		AppletInterpretadorPLP.SelecionarErro(id.getLineExpression(),
				id.getBeginColumnExpression(),
				id.getEndColumnExpression());
		System.out.println("Id");
	}

	/*@Override
	public void visit(ExpDeclaracao expDeclaracao, AmbienteCompilacao ambiente)
			throws VisitorException {
		AppletInterpretadorPLP.SelecionarErro(expDeclaracao.getExpressao().getLineExpression(),
				expDeclaracao.getExpressao().getBeginColumnExpression(),
				expDeclaracao.getExpressao().getEndColumnExpression());
		
	}*/
	
	@Override
	public void visit(Aplicacao aplicacao, AmbienteCompilacao ambiente){
		AppletInterpretadorPLP.SelecionarErro(aplicacao.getFunc().getLineExpression(),
				aplicacao.getFunc().getBeginColumnExpression(), aplicacao.getFunc().getEndColumnExpression());
		
	}
	
	@Override
	public void visit(IfThenElse ifThenElse, AmbienteCompilacao ambiente)
	throws VisitorException {
		
		AppletInterpretadorPLP.SelecionarErro(ifThenElse.getExpressao().getLineExpression(), 
				ifThenElse.getExpressao().getBeginColumnExpression(), ifThenElse.getExpressao().getEndColumnExpression());
		
	}

	@Override
	public void visit(While whileVar, AmbienteCompilacao ambiente)
			throws VisitorException {
		
		AppletInterpretadorPLP.SelecionarErro(whileVar.getExpressao().getLineExpression(), 
				whileVar.getExpressao().getBeginColumnExpression(), whileVar.getExpressao().getEndColumnExpression());	
	}

	@Override
	public void visit(Atribuicao atribuicao, AmbienteCompilacao ambiente)
			throws VisitorException {
		
		AppletInterpretadorPLP.SelecionarErro(atribuicao.getExpressao().getLineExpression(), 
				atribuicao.getExpressao().getBeginColumnExpression(), atribuicao.getExpressao().getEndColumnExpression());			
	}
}